(() => {
  const special = {
    "y": {//年
      "get":"getFullYear",
      "set":"setFullYear"
    },
    "m": {//月
      "get":"getMonth",
      "set":"setMonth"
    },
    "d": {//日
      "get":"getDate",
      "set":"setDate"
    },
    "h": {//时
      "get":"getHours",
      "set":"setHours"
    },
    "i": {//分
      "get":"getMinutes",
      "set":"setMinutes"
    },
    "s": {//秒
      "get":"getSeconds",
      "set":"setSeconds"
    },
    "ms": {//毫秒
      "get":"getMilliseconds",
      "set":"setMilliseconds"
    },
    "a": {//周
      "get":"getDay"
    },
  };
  /** 
  * 接收一系列的时间日期字符串并替换成相应的值,如：{y}-{m}-{d} {h}:{i}:{s}
  * new Date().format()
  **/
  if (!Date.prototype.format){
     Date.prototype.format = function(pattern?: string): string {
      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}",
        formatObj = {
          y: this.getFullYear(),
          m: this.getMonth() + 1,
          d: this.getDate(),
          h: this.getHours(),
          i: this.getMinutes(),
          s: this.getSeconds(),
          a: this.getDay()
        };
      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {

        let value = formatObj[key];
        // Note: getDay() returns 0 on Sunday
        if (key === "a") {
          return ["日", "一", "二", "三", "四", "五", "六"][value];
        }
        if (result.length > 0 && value < 10) {
          value = "0" + value;
        }
        return value || 0;
      });
      return time_str;
    }
  }

    /** 
    * 返回包含时间数值的对象
    * new Date().ToObject()
    **/
    if (!Date.prototype.ToObject){
      Date.prototype.ToObject = function(){
        return {
          y: this.getFullYear(),
          m: this.getMonth() + 1,
          d: this.getDate(),
          h: this.getHours(),
          i: this.getMinutes(),
          s: this.getSeconds(),
          ms: this.getMilliseconds(),
          a: this.getDay()
        }
      }
    }

    /** 
    * 克隆
    * new Date().clone()
    **/
    if (!Date.prototype.clone){
      Date.prototype.clone = function() {
        return new Date(this.valueOf());
      };
    }
    /** 
    * 设置时间，并返回设置后的时间
    * new Date().set('d',7)
    **/
    if (!Date.prototype.set){
      Date.prototype.set = function(unit: UnitType, value: number) {
        const d: Date = this.clone();
        if(special[unit]['set']){
          d[special[unit]['set']](value);
        }
       
        return d
      };
    }

    /** 
    * 获取时间
    * new Date().get('d')
    **/
    if (!Date.prototype.get){
      Date.prototype.get = function(unit: UnitType) {
        const d: Date = this.clone();
        return d[special[unit].get]();
      };
    }
    /** 
    * 获取指定时间增加后的时间
    * new Date().add(7, 'm')
    **/
    if (!Date.prototype.add){
      Date.prototype.add = function(value: number, unit?: UnitType) {
        
        unit = unit?unit:'d';
        const units: number = this.get(unit);
        const d = this.set(unit,units+value);
        return d;
      };
    }
    /** 
    * 获取指定时间减少后的时间
    * new Date().subtract(7, 'd')
    **/
    if (!Date.prototype.subtract){
      Date.prototype.subtract = function(value: number, unit?: UnitType) {
        
        unit = unit?unit:'d';
        const units: number = this.get(unit);
        const d = this.set(unit,units-value);
        return d;
      };
    }
    /** 
    * 时间差
    * new Date().diff(newday, 'd',true)
    **/
    if (!Date.prototype.diff){
      Date.prototype.diff = function(date: ConfigType, unit?: UnitType, float?: boolean) {
        const dif1: number = this.valueOf();
        unit = unit?unit:'ms';
        if(typeof date === 'string'){
          date = new Date(date)
        }else if(typeof date === 'number'){
          date = date.parseTime();
          date = new Date(date)
        }
        const dif2: number = date.valueOf();
        let difms: number = Math.abs(dif2-dif1);//毫秒
        let b = 1;
        switch(unit){
          case 's':
            b = 1000;//秒
            break
          case 'i':
            b = 1000*60;//分
            break
          case 'h':
            b = 1000*60*60;//时
            break
          case 'd':
            b = 1000*60*60*24;//日
            break
          case 'a':
            b = 1000*60*60*24*7;//周
            break
          case 'm':
            b = 1000*60*60*24*30;//月
            break
          case 'y':
            b = 1000*60*60*24*365;//年
            break
          default:
            b = 1
        }
        difms = difms/b
        if(float){
          difms = parseInt(difms.toFixed());
        }
        return difms;
      };
    }
    /** 
    * 是否之前
    * 检查一个 date 对象是否在另一个 date 对象时间之前。
    * new Date().isBefore(newday, 'year'); // false
    **/
    if (!Date.prototype.isBefore){
      Date.prototype.isBefore = function(date: ConfigType, unit?: UnitType) {
        let _this: number;
        let _that: number;
        if(typeof date === 'string'){
          date = new Date(date)
        }else if(typeof date === 'number'){
          date = date.parseTime();
          date = new Date(date);
        }
        if(unit){
          _this = this.get(unit);
          _that = date.get(unit);
        }else{
          _this = this.valueOf();
          _that = date.valueOf();
        }
        let re = false
        if(_this > _that){
          re = true
        }
        return re;
        
      };
    }

    /**
    * 是否之后
    * 检查一个 Date 对象是否在另一个 Date 对象时间之后。
    * new Date().isAfter(newday, 'y'); // false
    **/
    if (!Date.prototype.isAfter){
      Date.prototype.isAfter = function(date: ConfigType, unit?: UnitType) {
        let _this: number;
        let _that: number;
        if(typeof date === 'string'){
          date = new Date(date)
        }else if(typeof date === 'number'){
          date = date.parseTime();
          date = new Date(date)
        }
        if(unit){
          _this = this.get(unit);
          _that = date.get(unit);
        }else{
          _this = this.valueOf();
          _that = date.valueOf();
        }
        let re = false
        if(_this < _that){
          re = true
        }
        return re;
        
      };
    }
    /** 
    * 来展示一个时间是否介于两个时间之间.
    * new Date().IsBetween(day1,day2, 'y'); // false
    **/
    if (!Date.prototype.IsBetween){
      Date.prototype.IsBetween = function(date1: ConfigType,date2: ConfigType, unit?: UnitType) {
        let _this: number;
        let _that1: number;
        let _that2: number;
        if(typeof date1 === 'string'){
          date1 = new Date(date1)
        }else if(typeof date1 === 'number'){
          date1 = date1.parseTime();
          date1 = new Date(date1)
        }
        if(typeof date2 === 'string'){
          date2 = new Date(date2)
        }else if(typeof date2 === 'number'){
          date2 = date2.parseTime();
          date2 = new Date(date2)
        }
        if(unit){
          _this = this.get(unit);
          _that1 = date1.get(unit);
          _that2 = date2.get(unit);
        }else{
          _this = this.valueOf();
          _that1 = date1.valueOf();
          _that2 = date2.valueOf();
        }
        let re = false
        if(_that1< _this&&_this<_that2){
          re = true
        }
        return re;
        
      };
    }
    /** 
    * 是否相同
    * 检查一个 Date 对象是否和另一个 Date 对象时间相同。
    * new Date().isSame(newday, 'y'); // false
    **/
    if (!Date.prototype.isSame){
      Date.prototype.isSame = function(date: ConfigType, unit?: UnitType) {
        let _this: number;
        let _that: number;
        if(typeof date === 'string'){
          date = new Date(date)
        }else if(typeof date === 'number'){
          date = date.parseTime();
          date = new Date(date)
        }
        if(unit){
          _this = this.get(unit);
          _that = date.get(unit);
        }else{
          _this = this.valueOf();
          _that = date.valueOf();
        }
        let re = false
        if(_this === _that){
          re = true
        }
        return re;
        
      };
    }
    /** 
    * 天数 (月):返回月份的天数。
    * new Date().daysInMonth()
    **/
    if (!Date.prototype.daysInMonth){
      Date.prototype.daysInMonth = function() {
        const year = this.getFullYear();
        const month = this.getMonth()+1;
        const d = new Date(year, month, 0);
        return d.getDate();
      };
    }
})();

export { };


